package com.hjw.controller;

import cn.dev33.satoken.annotation.SaCheckRole;
import cn.dev33.satoken.annotation.SaMode;
import cn.dev33.satoken.stp.StpUtil;
import com.hjw.dao.LargeFileDao;
import com.hjw.entity.LargeFile;
import com.hjw.entity.PasswordEncoder;
import com.hjw.entity.User;
import com.hjw.service.UserService;
import com.hjw.utils.Utils;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.transaction.annotation.Propagation;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.web.bind.annotation.*;
import org.springframework.web.multipart.MultipartFile;

import java.io.IOException;
import java.util.HashMap;
import java.util.Map;

/**
 * <p>Project:Academic - UserController<p>
 *
 * @author IvanWei玮 -- maste
 * @version 1.0
 * @DataTime 2025/4/12 16:59
 * @since 1.8
 */
@Slf4j
@RestController
@SaCheckRole(value = {"adm","usr"} ,mode = SaMode.OR)
@RequestMapping("api/user")
public class UserController {

    @Autowired
    private UserService userService;
    @Autowired
    private PasswordEncoder passwordEncoder;
    @Autowired
    private LargeFileDao largeFileDao;

    @GetMapping("/checkToken")
    public String checkToken() {
        return Utils.reqSuccess("token", StpUtil.getTokenValue());
    }

    @GetMapping("/info")
    public String info() {
        int id = Integer.parseInt(StpUtil.getLoginId().toString());
        User user = userService.findById(id);
        return Utils.reqSuccess("用户信息", user);
    }
    @GetMapping("/shipInfo")  // /api/user/shipInfo
    public String shipInfo() {
        int id = Integer.parseInt(StpUtil.getLoginId().toString());
        User user = userService.findById(id);
        Map<String, String> result = new HashMap<>(2);
        result.put("name", user.getNickname());
        result.put("phone", user.getPhone());
        result.put("addr", user.getAddr());
        return Utils.reqSuccess("用户发货信息", result);
    }
    @PostMapping("/updatePwd") // /api/user/updatePwd
    public String updatePwd(String oldPwd, String newPwd){

        if (oldPwd == null || newPwd == null) {
            return Utils.reqOut(200,"参数错误", null);
        }
        int id = Integer.parseInt(StpUtil.getLoginId().toString());
        User user = userService.findById(id);

        if (!passwordEncoder.matches(oldPwd, user.getPassword())){
            log.info("密码比对错误，无法为用户：{} 进行修该",id);
            return Utils.reqOut(203, "旧密码错误", null);
        }
        if (oldPwd.equals(newPwd)){
            log.info("新密码与旧密码相同，无法为用户：{} 进行修该",id);
            return Utils.reqOut(203, "新密码与旧密码相同", null);
        }
        if (newPwd.length() < 6){
            log.info("新密码长度小于6，无法为用户：{} 进行修该",id);
            return Utils.reqOut(203, "新密码长度小于6", null);
        }
        if (newPwd.length() > 18){
            log.info("新密码长度大于18，无法为用户：{} 进行修该",id);
            return Utils.reqOut(203, "新密码长度大于18", null);
        }
        Map<String, Object> map = new HashMap<>(2);
        map.put("id",user.getId());
        map.put("password", passwordEncoder.encode(newPwd));
        int update = userService.update(map);
        if (update == 0){
            log.info("用户：{} 修改密码失败",id);
            return Utils.reqOut(203, "修改密码失败", null);
        }
        return Utils.reqSuccess("修改密码成功", null);
    }

    /**
     * 涉及到了操作两个表数据的操作，做最外层的事务（调用者事务）
     * @param myfile MultipartFile
     * @return String
     */
    @PostMapping("/updatePic") // /api/user/updatePic
    @Transactional(rollbackFor = Exception.class, propagation = Propagation.REQUIRED)
    public String updatePic(@RequestParam(value = "mypic", required = false) MultipartFile myfile) throws IOException {

        User user = userService.findById(Integer.parseInt(StpUtil.getLoginId().toString()));
        log.info("修改用户信息请求参数：{}", user);
        if (myfile == null || myfile.isEmpty()){
            log.info("头像上传失败");
            return Utils.reqSuccess("修改头像失败,失败原因在客户端", user.getImg());
        }
        // 先删除原来的图片，再添加新的图片
        int delete = largeFileDao.delete(user.getImg());
        log.info("删除用户原头像:{}", delete);
        LargeFile largeFile = new LargeFile();
        String[] split = user.getImg().split("\\.");
        // 添加新的图片(id = 原来的图片id?t=时间戳)
        largeFile.setId(split[0] +"."+System.currentTimeMillis());
        largeFile.setFilename(myfile.getOriginalFilename());
        largeFile.setContent(myfile.getBytes());
        int add = largeFileDao.add(largeFile);
        if (add == 0){
            log.info("头像上传失败，失败原因在处理图像层");
            return Utils.reqSuccess("修改头像失败", user.getImg());
        }
        log.info("头像上传成功:{}", largeFile);
        Map<String, Object> map = new HashMap<>(2);
        map.put("img", largeFile.getId());
        map.put("id", user.getId());
        log.info("修改用户信息请求参数：{}", map);
        //更新用户的图片id返回对象
        int update = userService.update(map);
        if (update == 0){
            log.info("头像上传失败,失败原因在用户层");
            return Utils.reqSuccess("修改头像失败", user.getImg());
        }
        return Utils.reqSuccess("修改头像成功", largeFile.getId());
    }

    @PostMapping("/updateShip") // /api/user/updateShip
    public String updateShip(@RequestBody Map<String, Object> map){


        log.info("修改收货信息请求参数：{}", map);
        // 清除客户端提交的无效信息
        String name = (String) map.get("name");
        if (name == null || name.isEmpty()){
            map.remove("name");
        }
        String phone = (String) map.get("phone");
        if (phone == null || phone.isEmpty()){
            map.remove("phone");
        }
        String addr = (String) map.get("addr");
        if (addr == null || addr.isEmpty()){
            map.remove("addr");
        }
        if (map.isEmpty()){
            log.info("修改收货信息失败，客户端提交的信息为空");
            return Utils.reqOut(203, "修改收货信息失败", null);
        }
        map.put("id", Integer.parseInt(StpUtil.getLoginId().toString()));
        int update = userService.update(map);

        if (update == 0){
            log.info("修改收货信息失败");
            return Utils.reqOut(203, "修改收货信息失败", null);
        }
        log.info("修改收货信息成功");
        return Utils.reqSuccess("修改收货信息成功", null);
    }

    @GetMapping("/comment") // /api/user/comment 评论
    public String comment(){
        return Utils.reqSuccess("评论成功", null);
    }

}
